
#include "TypeSerializer.h"
#include "Common/Strings.h"

using namespace ttg_internal::utils;

//----------------------
//--- TypeSerializer ---
//----------------------

std::string TypeSerializer::serializeInt64(ttg::math::int64 lo, ttg::math::int64 hi)
{
	char buf[1024];
	sprintf_s(buf, 1024, "Int64[%lld,%lld]", lo, hi);
	return buf;
}

std::string TypeSerializer::serializeDouble(double lo, double hi)
{
	char buf[1024];
	sprintf_s(buf, 1024, "Double[%lf,%lf]", lo, hi);
	return buf;
}

std::string TypeSerializer::serializeEnum(std::vector<std::string> &elements)
{
	//Checking.
	if (elements.size() == 0)
		return "Enum";
	//Serializing.
	std::string res = "Enum{";
	res.append(elements[0]);
	for (size_t i = 1; i < elements.size(); i++)
	{
		res.append(",");
		res.append(elements[i]);
	}
	res.append("}");
	return res;
}

TypeSerializer::ParameterType TypeSerializer::deserializeType(const char *type)
{
	//Configuring.
	ttg::strings::StringSplitter sp;
	sp.setSplitter('{', false);
	sp.setSplitter('}', false);
	sp.setSplitter('[', false);
	sp.setSplitter(']', false);
	sp.setSplitter(',', false);
	sp.setString(type);
	//Detecting.
	if (sp.getCount() == 0 || sp[0] == std::string("Void"))
		return Void;
	if (sp[0] == std::string("Bool"))
		return Bool;
	if (sp[0] == std::string("String"))
		return String;
	if (sp[0] == std::string("Int64"))
		return Int64;
	if (sp[0] == std::string("Double"))
		return Double;
	if (sp[0] == std::string("Enum"))
		return Enum;
	return Void;
}

bool TypeSerializer::deserializeInt64Bounds(const char *type,
											ttg::math::int64 &lo,
											ttg::math::int64 &hi)
{
	//Configuring.
	ttg::strings::StringSplitter sp;
	sp.setSplitter('{', false);
	sp.setSplitter('}', false);
	sp.setSplitter('[', false);
	sp.setSplitter(']', false);
	sp.setSplitter(',', false);
	sp.setString(type);
	//Getting.
	if (sp.getCount() != 3 ||
		!ttg::strings::isInt(sp[1], lo) ||
		!ttg::strings::isInt(sp[2], hi))
		return false;
	return true;
}

bool TypeSerializer::deserializeDoubleBounds(const char *type, double &lo, double &hi)
{
	//Configuring.
	ttg::strings::StringSplitter sp;
	sp.setSplitter('{', false);
	sp.setSplitter('}', false);
	sp.setSplitter('[', false);
	sp.setSplitter(']', false);
	sp.setSplitter(',', false);
	sp.setString(type);
	//Getting.
	if (sp.getCount() != 3 ||
		!ttg::strings::isFloat(sp[1], lo) ||
		!ttg::strings::isFloat(sp[2], hi))
		return false;
	return true;
}

std::vector<std::string> TypeSerializer::deserializeEnumElements(const char *type)
{
	//Configuring.
	ttg::strings::StringSplitter sp;
	sp.setSplitter('{', false);
	sp.setSplitter('}', false);
	sp.setSplitter('[', false);
	sp.setSplitter(']', false);
	sp.setSplitter(',', false);
	sp.setString(type);
	//Building result.
	std::vector<std::string> res;
	for (size_t i = 1; i < sp.getCount(); i++)
		res.push_back(std::string(sp[i]));
	return res;
}
